package com.morningstar.keyratio;

import java.io.IOException;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class MorningStarKeyRatioUtils {
	private static String url = "http://financials.morningstar.com/finan/ajax/exportKR2CSV.html?&callback=?&t={exchange}:{code}&region=usa&culture=en-US&cur=&order=asc";
	
	public static KeyRatioEntity fetchStockData(String exchange,String code){
		KeyRatioEntity entity = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpGet httpget = new HttpGet(url.replace("{exchange}", exchange).replace("{code}", code));

            ResponseHandler<String> responseHandler = new ResponseHandler<String>() {

                @Override
                public String handleResponse(
                        final HttpResponse response) throws ClientProtocolException, IOException {
                    int status = response.getStatusLine().getStatusCode();
                    if (status >= 200 && status < 300) {
                        HttpEntity entity = response.getEntity();
                        return entity != null ? EntityUtils.toString(entity) : null;
                    } else {
                        throw new ClientProtocolException("Unexpected response status: " + status);
                    }
                }

            };
            String responseBody = httpclient.execute(httpget, responseHandler);
            System.out.println("----------------------------------------");
            //System.out.println(responseBody);
            //System.out.println("////////////////////////////////////////");
            
            entity = new KeyRatioEntity(responseBody);
          
         
        } catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
        finally {
            try {
				httpclient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
        }
        
        fixEntity(entity);
        return entity;
	}
	
	public static KeyRatioEntity fetchStockData(String exchange,String code,int assureTimes){
		KeyRatioEntity entity = null;
		for(int i=0;i<assureTimes;i++){
			entity = fetchStockData(exchange,code);
			if(entity != null)break;
		}
		
		fixEntity(entity);
		return entity;
	}
	
	/**
	 * Add default title for sub-section which title is empty
	 * Fix Growth section indices
	 * @param entity
	 */
	private static void fixEntity(KeyRatioEntity entity){
		List<KeyRatioEntity.Section> sections = entity.getSections();
		KeyRatioEntity.SubSection growthSubSection = null;
		for(int i=0;i<sections.size();i++){
			KeyRatioEntity.Section section = sections.get(i);
			
			for(int j=0;j<section.getSubSections().size();j++){
				if(section.getSubSections().get(j).getTitle().equals("")){
					section.getSubSections().get(j).setTitle(section.getTitle());
				}
				
				if(section.getSubSections().get(j).getTitle().contains(Constants.SUBSECTION_GROWTH_MARK)){
					growthSubSection = section.getSubSections().get(j);
				}
			}
		}
		
		if(growthSubSection != null){
			List<KeyRatioEntity.KeyIndex> indices = growthSubSection.getIndices();
			for(int i=0;i<indices.size();i++){
				switch (indices.get(i).getTitle()) {
					case Constants.INDEX_GROWTH_REVENUE_MARK:
						setGrowthIndexTitle(indices,i,Constants.INDEX_GROWTH_REVENUE_MARK);
						break;
					case Constants.INDEX_GROWTH_NETINCOME_MARK:
						setGrowthIndexTitle(indices,i,Constants.INDEX_GROWTH_NETINCOME_MARK);
						break;
					case Constants.INDEX_GROWTH_OPTINCOME_MARK:
						setGrowthIndexTitle(indices,i,Constants.INDEX_GROWTH_OPTINCOME_MARK);
						break;
					case Constants.INDEX_GROWTH_EPS_MARK:
						setGrowthIndexTitle(indices,i,Constants.INDEX_GROWTH_EPS_MARK);
						break;
					default:
						break;
				}
			}
			
			indices.removeIf(idx -> idx.getTitle().equals(Constants.INDEX_GROWTH_REVENUE_MARK) || 
								idx.getTitle().equals(Constants.INDEX_GROWTH_NETINCOME_MARK) ||
								idx.getTitle().equals(Constants.INDEX_GROWTH_OPTINCOME_MARK) ||
								idx.getTitle().equals(Constants.INDEX_GROWTH_EPS_MARK));
		}
	}
	
	private static void setGrowthIndexTitle(List<KeyRatioEntity.KeyIndex> indices,int idx,String prefix){
		indices.get(idx+1).setTitle(prefix + " -> " + indices.get(idx+1).getTitle());
		indices.get(idx+2).setTitle(prefix + " -> " + indices.get(idx+2).getTitle());
		indices.get(idx+3).setTitle(prefix + " -> " + indices.get(idx+3).getTitle());
		indices.get(idx+4).setTitle(prefix + " -> " + indices.get(idx+4).getTitle());
	}
	
	public static void main(String[] args) throws Exception{
		System.out.println(fetchStockData("XNYS","IBM",5));
	}
	
}
